package com.treetao.union.core.tencent.mp;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSONObject;
import com.treetao.union.core.exception.DevMException;
import com.treetao.union.core.redis.RedisService;
import com.treetao.union.core.tencent.mp.entity.WebviewAuthResult;
import com.treetao.union.core.util.HttpKit;

import lombok.extern.slf4j.Slf4j;

/**
 * 微信网页授权服务
 * @author Dev.M
 *
 */
@Component
@Slf4j
public class TencentWebviewAuthService {
	private static final String url_snsapi_base = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=snsapi_base&state=%s#wechat_redirect";
	private static final String url_snsapi_userinfo = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=snsapi_userinfo&state=%s#wechat_redirect";
	private static final String url_access_token = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code";
	private static final String url_refresh_token = "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=%s&grant_type=refresh_token&refresh_token=%s";
	private static final String url_getuserinfo = "https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_CN";
	private final static String tencent_webview_access_token = "tencent_webview_access_token";
	private final static String tencent_refresh_access_token = "tencent_webview_refresh_token";
	
	@Autowired
	private RedisService redisService;
	
	/**
	 * 通过scope为snsapi_base静默授权
	 * （不弹出授权页面，直接跳转，只能获取用户openid）
	 * @param appid
	 * @param redirectUrl
	 * @param state 开发者可以填写a-zA-Z0-9的参数值，最多128字节
	 * @return 
	 */
	public String call_getcode_auth_snsapi_base(String appid,String redirect_uri,String state) {
		return String.format(url_snsapi_base, appid,redirect_uri,state);
	}
	
	/**
	 * 通过scope为snsapi_userinfo形式调出微信授权页面
	 * @param appid
	 * @param redirect_uri
	 * @param state 开发者可以填写a-zA-Z0-9的参数值，最多128字节
	 * @return 如果用户同意授权，页面将跳转至 redirect_uri/?code=CODE&state=STATE。
	 */
	public String call_getcode_auth_snsapi_userinfo(String appid,String redirect_uri,String state) {
		return String.format(url_snsapi_userinfo, appid,redirect_uri,state);
	}
	
	/**
	 * 通过code换取的是一个特殊的网页授权access_token,与基础支持中的access_token（该access_token用于调用其他接口）不同。公众号可通过下述接口来获取网页授权access_token。
	 * 1)如果网页授权的作用域为snsapi_base，则本步骤中获取到网页授权access_token的同时，也获取到了openid;
	 * 2)snsapi_base式的网页授权流程即到此为止
	 * @param appid
	 * @param secret
	 * @param code 第一步获取到的code
	 */
	public WebviewAuthResult getWebviewAccessToken(String appid,String secret,String code) {
		WebviewAuthResult was = new WebviewAuthResult();
		if (redisService.hasKey(tencent_webview_access_token)) {
			//已存在有效的token
			String access_token = redisService.get(tencent_webview_access_token).toString();
			log.info("从redis中获取webview_access_token --> " + access_token);
			was.setAccessToken(access_token);
		} else {
			String url = null;
			//查看refreshtoken是否有效，如果有效，则刷新accesstoken
			if (redisService.hasKey(tencent_refresh_access_token)) {
				String refresh_token = redisService.get(tencent_refresh_access_token).toString();
				url = String.format(url_refresh_token, appid,refresh_token);
			} else {
				url = String.format(url_access_token, appid,secret,code);
			}
			String jstoken = HttpKit.get(url);
			JSONObject json = JSONObject.parseObject(jstoken);
			if (json.getInteger("errcode") !=null && json.getInteger("errcode")!=0) {
				throw new DevMException(json.getString("errmsg"));
			}
			String access_token = json.getString("access_token");
			String refresh_token = json.getString("refresh_token");
			String openid = json.getString("openid");
		//	String scope = json.getString("scope");//用户授权的作用域，使用逗号（,）分隔
			int expires_in = json.getIntValue("expires_in");
			
			redisService.set(tencent_webview_access_token, access_token,expires_in);
			redisService.set(tencent_refresh_access_token, refresh_token,30*24*60*60);//refresh_token有效期为30天
			
			was.setOpenid(openid);
			was.setAccessToken(access_token);
		}
		return was;
	}
	
	/**
	 * 拉取用户信息(需scope为 snsapi_userinfo)
	 * @param access_token
	 * @param openid
	 * @return
	 */
	public WebviewAuthResult getUserInfo(String access_token,String openid) {
		String url = String.format(url_getuserinfo, access_token,openid);
		String str = HttpKit.get(url);
		WebviewAuthResult was = JSONObject.parseObject(str, WebviewAuthResult.class);
		if(was.getErrcode()!=null && was.getErrcode()!=0) {
			throw new DevMException(was.getErrmsg());
		}
		return was;
	}
}
